library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ───────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.2 ✓ purrr 0.3.4
✓ tibble 3.0.3 ✓ dplyr 1.0.2
✓ tidyr 1.1.1 ✓ stringr 1.4.0
✓ readr 1.3.1 ✓ forcats 0.5.0
── Conflicts ──────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag() masks stats::lag()
library(janitor)
Attaching package: ‘janitor’
The following objects are masked from ‘package:stats’:
chisq.test, fisher.test
library(lubridate)
Attaching package: ‘lubridate’
The following objects are masked from ‘package:base’:
date, intersect, setdiff, union
library(plotly)
Registered S3 method overwritten by 'data.table':
method from
print.data.table
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
astronauts = read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-07-14/astronauts.csv')
Parsed with column specification:
cols(
.default = col_double(),
name = col_character(),
original_name = col_character(),
sex = col_character(),
nationality = col_character(),
military_civilian = col_character(),
selection = col_character(),
occupation = col_character(),
mission_title = col_character(),
ascend_shuttle = col_character(),
in_orbit = col_character(),
descend_shuttle = col_character()
)
See spec(...) for full column specifications.
astronauts = astronauts %>%
mutate(
sex = as.factor(sex),
year_of_birth = year(parse_date(as.character(astronauts$year_of_birth), "%Y")),
nationality = as.factor(nationality),
selection = as.factor(selection),
year_of_selection = year(parse_date(as.character(astronauts$year_of_selection), "%Y")),
mission_number = as.factor(mission_number),
occupation = as.factor(occupation),
year_of_mission = year(parse_date(as.character(astronauts$year_of_mission), "%Y")),
mission_title = as.factor(mission_title),
ascend_shuttle = as.factor(ascend_shuttle),
in_orbit = as.factor(in_orbit),
descend_shuttle = as.factor(descend_shuttle)
)
astronauts
launches = read_csv("https://raw.githubusercontent.com/TheEconomist/graphic-detail-data/master/data/2018-10-20_space-launches/launches.csv")
Parsed with column specification:
cols(
tag = col_character(),
JD = col_double(),
launch_date = col_date(format = ""),
launch_year = col_double(),
type = col_character(),
variant = col_character(),
mission = col_character(),
agency = col_character(),
state_code = col_character(),
category = col_character(),
agency_type = col_character()
)
launches = within.data.frame(launches, rm(tag, JD))
launches = launches %>%
mutate(
type = as.factor(type),
variant = as.factor(variant),
state_code = as.factor(state_code),
category = as.factor(category),
agency_type = as.factor(agency_type)
)
launches = launches %>% filter(launch_date<=Sys.Date())
require(countrycode)
Loading required package: countrycode
launches = launches %>%
mutate(
state_code = fct_collapse(
state_code,
"RU" = c("SU", "RU"),
"FR" = "F",
"JP" = "J",
"IT" = "I",
"FR" = c("I-ESA", "I-ELDO"),
"KY" = "CYM",
"GB" = "UK")
) %>%
mutate(state_code = countrycode(state_code, "iso2c", "country.name"),
state_code = as.factor(state_code))
agencies = read_csv("https://raw.githubusercontent.com/TheEconomist/graphic-detail-data/master/data/2018-10-20_space-launches/agencies.csv")
Parsed with column specification:
cols(
agency = col_character(),
count = col_double(),
ucode = col_character(),
state_code = col_character(),
type = col_character(),
class = col_character(),
tstart = col_character(),
tstop = col_character(),
short_name = col_character(),
name = col_character(),
location = col_character(),
longitude = col_character(),
latitude = col_character(),
error = col_character(),
parent = col_character(),
short_english_name = col_character(),
english_name = col_character(),
unicode_name = col_character(),
agency_type = col_character()
)
agencies = agencies %>%
mutate(
tstart = parse_date(as.character(tstart), "%Y %b %d"),
tstop = parse_date(as.character(tstop), "%Y %b %d"),
agency_type = as.factor(agency_type)
)
Problem with `mutate()` input `tstart`.
ℹ 55 parsing failures.
row col expected actual
1 -- date like %Y %b %d 1960
7 -- date like %Y %b %d 1997 Jul
9 -- date like %Y %b %d 2004
10 -- date like %Y %b %d 1993
11 -- date like %Y %b %d 1995
... ... .................. ........
See problems(...) for more details.
ℹ Input `tstart` is `parse_date(as.character(tstart), "%Y %b %d")`.55 parsing failures.
row col expected actual
1 -- date like %Y %b %d 1960
7 -- date like %Y %b %d 1997 Jul
9 -- date like %Y %b %d 2004
10 -- date like %Y %b %d 1993
11 -- date like %Y %b %d 1995
... ... .................. ........
See problems(...) for more details.
Problem with `mutate()` input `tstop`.
ℹ 63 parsing failures.
row col expected actual
1 -- date like %Y %b %d 1991 Dec
2 -- date like %Y %b %d 1991
3 -- date like %Y %b %d -
4 -- date like %Y %b %d -
5 -- date like %Y %b %d *
... ... .................. ........
See problems(...) for more details.
ℹ Input `tstop` is `parse_date(as.character(tstop), "%Y %b %d")`.63 parsing failures.
row col expected actual
1 -- date like %Y %b %d 1991 Dec
2 -- date like %Y %b %d 1991
3 -- date like %Y %b %d -
4 -- date like %Y %b %d -
5 -- date like %Y %b %d *
... ... .................. ........
See problems(...) for more details.
agencies
launches %>%
count(launch_year, agency_type)
launches %>%
count(launch_year, agency_type) %>%
ggplot(aes(launch_year, n, color= agency_type)) +geom_line() +
labs(x = "Year", y = "Launch Counts", color="Agency Type")

launches %>%
count(launch_year, agency_type) %>%
plot_ly(x = ~launch_year, y = ~n, color=~agency_type, type = 'scatter', mode = 'lines')
`arrange_()` is deprecated as of dplyr 0.7.0.
Please use `arrange()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
launches %>%
mutate(type = fct_reorder(type, launch_date, min)) %>%
ggplot(aes(x=launch_date, y=state_code, color=agency_type)) +
geom_jitter(alpha=0.2, height = 0.2) +
theme_minimal() +
facet_grid(agency_type~., scales = 'free') +
labs(x= "# of Agencies",
y="",
color='Agency Type',
title = '# of Agencies in different countries Countries')

launches %>%
count(agency_type, state_code, sort=T) %>%
plot_ly(y = ~state_code, x = ~n, color = ~agency_type, type="bar") %>%
layout(legend = list(title=list(text='Agency Type')),
xaxis = list(title = "# of Agencies", type = "log"),
yaxis = list(title = ""),
title = '# of Agencies in different countries Countries')
launches %>%
mutate(state_code = fct_lump(state_code, 6)) %>%
count(launch_year, state_code, sort=T) %>%
mutate(state_code = fct_reorder(state_code, -n, sum))%>%
ggplot(aes(launch_year, n, color=state_code)) + geom_line() +
labs(x= "Launch Year",
y = "Launch Counts",
color= "Countries",
title= "Yearly Launch Counts wrt Countries")

launches %>%
mutate(state_code = fct_lump(state_code, 6)) %>%
count(launch_year, state_code, sort=T) %>%
mutate(state_code = fct_reorder(state_code, -n, sum)) %>%
plot_ly(x = ~launch_year, y = ~n, color=~state_code) %>%
add_lines() %>%
layout(legend = list(title=list(text='Countries')),
xaxis = list(title = "Launch Year"),
yaxis = list(title = "Launch Counts"),
title = 'Yearly Launch Counts wrt Countries')
launches %>%
filter(agency_type%in%c("private","startup")) %>%
inner_join(agencies %>% select(agency, name, short_name, parent), by = 'agency') %>%
ggplot(aes(y=name, fill = state_code)) + geom_bar() +
facet_grid(state_code~., scales = 'free', space = 'free') +
labs(x= "Launch Counts", y = "",
fill= "Countries",
title= "Yearly Launch Counts wrt Private owned Agencies in different countries") +
theme(strip.text.y = element_blank())

launches %>%
filter(agency_type%in%c("private","startup")) %>%
inner_join(agencies %>% select(agency, name, short_name, parent), by = 'agency') %>%
count(launch_year, state_code, sort=T) %>%
mutate(state_code=fct_reorder(state_code, launch_year)) %>%
plot_ly(x=~n, y= ~launch_year, color=~state_code, colors="Dark2", type='bar') %>%
layout(barmode='stack',
legend = T,
xaxis = list(title = "Launch Counts"),
yaxis = list(title = "", showticklabels = F),
title = "Launch Counts of Companies not handled by Government")
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Dark2 is 8
Returning the palette you asked for with that many colors
launches %>%
count(agency_type, state_code, sort=T) %>%
mutate(state_code = fct_reorder(state_code, n)) %>%
plot_ly(x=~n, y=~state_code, color=~agency_type) %>%
layout(barmode='stack',
xaxis=list(type='log', title = "", showticklabels = F),
yaxis=list(title = ""),
title= 'Space Programs among Countries')
No trace type specified:
Based on info supplied, a 'bar' trace seems appropriate.
Read more about this trace type -> https://plot.ly/r/reference/#bar
No trace type specified:
Based on info supplied, a 'bar' trace seems appropriate.
Read more about this trace type -> https://plot.ly/r/reference/#bar
russian_vehicles = launches %>%
filter(state_code=='Russia') %>%
group_by(type, state_code) %>%
summarise(earliest=min(launch_year), latest=max(launch_year), counts=n()) %>%
ungroup()%>%
arrange(-counts) %>% filter(counts>=mean(counts))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
launches %>%
semi_join(russian_vehicles, by='type')%>%
mutate(type = fct_reorder(type, launch_date, min)) %>%
ggplot(aes(x=launch_date, y=type, color=type)) +
geom_jitter(alpha=0.2, height = 0.2, show.legend = F) +
theme(legend.position = 'none')+ theme_minimal()+
labs(title = 'Russian Space Vehicle Timeline',
subtitle = "Only greater than 30 launches",
x= "Launch Date", y="Vehicle")

launches %>%
filter(state_code=='United States')%>%
add_count(type) %>% filter(n>=mean(n)) %>%
mutate(type = fct_reorder(type, launch_date, min)) %>%
ggplot(aes(x=launch_date, y=type, color=agency_type)) +
geom_jitter(alpha=0.2, height = 0.2) + theme_minimal()+
labs(title = 'US Space Vehicle Timeline',
x= "Launch Date", y="Vehicle", color='Agency Type')

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoamFuaXRvcikKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocGxvdGx5KQpgYGAKCgpgYGB7cn0KYXN0cm9uYXV0cyA9IHJlYWRfY3N2KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMjAvMjAyMC0wNy0xNC9hc3Ryb25hdXRzLmNzdicpCmFzdHJvbmF1dHMgPSBhc3Ryb25hdXRzICU+JSAKICBtdXRhdGUoCiAgICBzZXggPSBhcy5mYWN0b3Ioc2V4KSwKICAgIHllYXJfb2ZfYmlydGggPSB5ZWFyKHBhcnNlX2RhdGUoYXMuY2hhcmFjdGVyKGFzdHJvbmF1dHMkeWVhcl9vZl9iaXJ0aCksICIlWSIpKSwKICAgIG5hdGlvbmFsaXR5ID0gYXMuZmFjdG9yKG5hdGlvbmFsaXR5KSwKICAgIHNlbGVjdGlvbiA9IGFzLmZhY3RvcihzZWxlY3Rpb24pLAogICAgeWVhcl9vZl9zZWxlY3Rpb24gPSB5ZWFyKHBhcnNlX2RhdGUoYXMuY2hhcmFjdGVyKGFzdHJvbmF1dHMkeWVhcl9vZl9zZWxlY3Rpb24pLCAiJVkiKSksCiAgICBtaXNzaW9uX251bWJlciA9IGFzLmZhY3RvcihtaXNzaW9uX251bWJlciksCiAgICBvY2N1cGF0aW9uID0gYXMuZmFjdG9yKG9jY3VwYXRpb24pLAogICAgeWVhcl9vZl9taXNzaW9uID0geWVhcihwYXJzZV9kYXRlKGFzLmNoYXJhY3Rlcihhc3Ryb25hdXRzJHllYXJfb2ZfbWlzc2lvbiksICIlWSIpKSwKICAgIG1pc3Npb25fdGl0bGUgPSBhcy5mYWN0b3IobWlzc2lvbl90aXRsZSksCiAgICBhc2NlbmRfc2h1dHRsZSA9IGFzLmZhY3Rvcihhc2NlbmRfc2h1dHRsZSksCiAgICBpbl9vcmJpdCA9IGFzLmZhY3Rvcihpbl9vcmJpdCksCiAgICBkZXNjZW5kX3NodXR0bGUgPSBhcy5mYWN0b3IoZGVzY2VuZF9zaHV0dGxlKQogICkKYXN0cm9uYXV0cwpgYGAKCgpgYGB7cn0KbGF1bmNoZXMgPSByZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL1RoZUVjb25vbWlzdC9ncmFwaGljLWRldGFpbC1kYXRhL21hc3Rlci9kYXRhLzIwMTgtMTAtMjBfc3BhY2UtbGF1bmNoZXMvbGF1bmNoZXMuY3N2IikKbGF1bmNoZXMgPSB3aXRoaW4uZGF0YS5mcmFtZShsYXVuY2hlcywgcm0odGFnLCBKRCkpCmxhdW5jaGVzID0gbGF1bmNoZXMgJT4lCiAgbXV0YXRlKAogICAgdHlwZSA9IGFzLmZhY3Rvcih0eXBlKSwgCiAgICB2YXJpYW50ID0gYXMuZmFjdG9yKHZhcmlhbnQpLAogICAgc3RhdGVfY29kZSA9IGFzLmZhY3RvcihzdGF0ZV9jb2RlKSwgCiAgICBjYXRlZ29yeSA9IGFzLmZhY3RvcihjYXRlZ29yeSksCiAgICBhZ2VuY3lfdHlwZSA9IGFzLmZhY3RvcihhZ2VuY3lfdHlwZSkKICAgICkKbGF1bmNoZXMgPSBsYXVuY2hlcyAlPiUgZmlsdGVyKGxhdW5jaF9kYXRlPD1TeXMuRGF0ZSgpKQoKcmVxdWlyZShjb3VudHJ5Y29kZSkKCmxhdW5jaGVzID0gbGF1bmNoZXMgJT4lCiAgbXV0YXRlKAogICAgc3RhdGVfY29kZSA9IGZjdF9jb2xsYXBzZSgKICAgICAgc3RhdGVfY29kZSwKICAgICAgIlJVIiA9IGMoIlNVIiwgIlJVIiksCiAgICAgICJGUiIgPSAiRiIsCiAgICAgICJKUCIgPSAiSiIsCiAgICAgICJJVCIgPSAiSSIsCiAgICAgICJGUiIgPSBjKCJJLUVTQSIsICJJLUVMRE8iKSwKICAgICAgIktZIiA9ICJDWU0iLAogICAgICAiR0IiID0gIlVLIikKICAgICkgJT4lCiAgbXV0YXRlKHN0YXRlX2NvZGUgPSBjb3VudHJ5Y29kZShzdGF0ZV9jb2RlLCAiaXNvMmMiLCAiY291bnRyeS5uYW1lIiksCiAgICAgICAgIHN0YXRlX2NvZGUgPSBhcy5mYWN0b3Ioc3RhdGVfY29kZSkpCmBgYAoKCmBgYHtyfQphZ2VuY2llcyA9IHJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vVGhlRWNvbm9taXN0L2dyYXBoaWMtZGV0YWlsLWRhdGEvbWFzdGVyL2RhdGEvMjAxOC0xMC0yMF9zcGFjZS1sYXVuY2hlcy9hZ2VuY2llcy5jc3YiKQphZ2VuY2llcyA9IGFnZW5jaWVzICU+JQogIG11dGF0ZSgKICAgIHRzdGFydCA9IHBhcnNlX2RhdGUoYXMuY2hhcmFjdGVyKHRzdGFydCksICIlWSAlYiAlZCIpLAogICAgdHN0b3AgPSBwYXJzZV9kYXRlKGFzLmNoYXJhY3Rlcih0c3RvcCksICIlWSAlYiAlZCIpLAogICAgYWdlbmN5X3R5cGUgPSBhcy5mYWN0b3IoYWdlbmN5X3R5cGUpCiAgKQphZ2VuY2llcwpgYGAKCgpgYGB7cn0KbGF1bmNoZXMgJT4lCiAgY291bnQobGF1bmNoX3llYXIsIGFnZW5jeV90eXBlKQoKCmxhdW5jaGVzICU+JQogIGNvdW50KGxhdW5jaF95ZWFyLCBhZ2VuY3lfdHlwZSkgJT4lCiAgZ2dwbG90KGFlcyhsYXVuY2hfeWVhciwgbiwgY29sb3I9IGFnZW5jeV90eXBlKSkgK2dlb21fbGluZSgpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiTGF1bmNoIENvdW50cyIsIGNvbG9yPSJBZ2VuY3kgVHlwZSIpCgpsYXVuY2hlcyAlPiUKICBjb3VudChsYXVuY2hfeWVhciwgYWdlbmN5X3R5cGUpICU+JQogIHBsb3RfbHkoeCA9IH5sYXVuY2hfeWVhciwgeSA9IH5uLCBjb2xvcj1+YWdlbmN5X3R5cGUsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnKQpgYGAKCmBgYHtyfQpsYXVuY2hlcyAlPiUgCiAgbXV0YXRlKHR5cGUgPSBmY3RfcmVvcmRlcih0eXBlLCBsYXVuY2hfZGF0ZSwgbWluKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxhdW5jaF9kYXRlLCB5PXN0YXRlX2NvZGUsIGNvbG9yPWFnZW5jeV90eXBlKSkgKyAKICBnZW9tX2ppdHRlcihhbHBoYT0wLjIsIGhlaWdodCA9IDAuMikgKyAKICB0aGVtZV9taW5pbWFsKCkgKwogIGZhY2V0X2dyaWQoYWdlbmN5X3R5cGV+Liwgc2NhbGVzID0gJ2ZyZWUnKSArIAogIGxhYnMoeD0gIiMgb2YgQWdlbmNpZXMiLCAKICAgICAgIHk9IiIsIAogICAgICAgY29sb3I9J0FnZW5jeSBUeXBlJywKICAgICAgIHRpdGxlID0gJyMgb2YgQWdlbmNpZXMgaW4gZGlmZmVyZW50IGNvdW50cmllcyBDb3VudHJpZXMnKQoKbGF1bmNoZXMgJT4lIAogIGNvdW50KGFnZW5jeV90eXBlLCBzdGF0ZV9jb2RlLCBzb3J0PVQpICU+JQogIHBsb3RfbHkoeSA9IH5zdGF0ZV9jb2RlLCB4ID0gfm4sIGNvbG9yID0gfmFnZW5jeV90eXBlLCB0eXBlPSJiYXIiKSAlPiUKICBsYXlvdXQobGVnZW5kID0gbGlzdCh0aXRsZT1saXN0KHRleHQ9J0FnZW5jeSBUeXBlJykpLCAKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiMgb2YgQWdlbmNpZXMiLCB0eXBlID0gImxvZyIpLCAKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLCAKICAgICAgICAgdGl0bGUgPSAnIyBvZiBBZ2VuY2llcyBpbiBkaWZmZXJlbnQgY291bnRyaWVzIENvdW50cmllcycpCmBgYAoKYGBge3J9CmxhdW5jaGVzICU+JQogIG11dGF0ZShzdGF0ZV9jb2RlID0gZmN0X2x1bXAoc3RhdGVfY29kZSwgNikpICU+JQogIGNvdW50KGxhdW5jaF95ZWFyLCBzdGF0ZV9jb2RlLCBzb3J0PVQpICU+JQogIG11dGF0ZShzdGF0ZV9jb2RlID0gZmN0X3Jlb3JkZXIoc3RhdGVfY29kZSwgLW4sIHN1bSkpJT4lCiAgZ2dwbG90KGFlcyhsYXVuY2hfeWVhciwgbiwgY29sb3I9c3RhdGVfY29kZSkpICsgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHg9ICJMYXVuY2ggWWVhciIsIAogICAgICAgeSA9ICJMYXVuY2ggQ291bnRzIiwgCiAgICAgICBjb2xvcj0gIkNvdW50cmllcyIsIAogICAgICAgdGl0bGU9ICJZZWFybHkgTGF1bmNoIENvdW50cyB3cnQgQ291bnRyaWVzIikKCmxhdW5jaGVzICU+JQogIG11dGF0ZShzdGF0ZV9jb2RlID0gZmN0X2x1bXAoc3RhdGVfY29kZSwgNikpICU+JQogIGNvdW50KGxhdW5jaF95ZWFyLCBzdGF0ZV9jb2RlLCBzb3J0PVQpICU+JQogIG11dGF0ZShzdGF0ZV9jb2RlID0gZmN0X3Jlb3JkZXIoc3RhdGVfY29kZSwgLW4sIHN1bSkpICU+JQogIHBsb3RfbHkoeCA9IH5sYXVuY2hfeWVhciwgeSA9IH5uLCBjb2xvcj1+c3RhdGVfY29kZSkgJT4lIAogIGFkZF9saW5lcygpICU+JSAKICBsYXlvdXQobGVnZW5kID0gbGlzdCh0aXRsZT1saXN0KHRleHQ9J0NvdW50cmllcycpKSwgCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJMYXVuY2ggWWVhciIpLCAKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkxhdW5jaCBDb3VudHMiKSwgCiAgICAgICAgIHRpdGxlID0gJ1llYXJseSBMYXVuY2ggQ291bnRzIHdydCBDb3VudHJpZXMnKQpgYGAKCgpgYGB7cn0KbGF1bmNoZXMgJT4lCiAgZmlsdGVyKGFnZW5jeV90eXBlJWluJWMoInByaXZhdGUiLCJzdGFydHVwIikpICU+JQogIGlubmVyX2pvaW4oYWdlbmNpZXMgJT4lIHNlbGVjdChhZ2VuY3ksIG5hbWUsIHNob3J0X25hbWUsIHBhcmVudCksIGJ5ID0gJ2FnZW5jeScpICAlPiUKICBnZ3Bsb3QoYWVzKHk9bmFtZSwgZmlsbCA9IHN0YXRlX2NvZGUpKSArIGdlb21fYmFyKCkgKyAKICBmYWNldF9ncmlkKHN0YXRlX2NvZGV+Liwgc2NhbGVzID0gJ2ZyZWUnLCBzcGFjZSA9ICdmcmVlJykgKyAKICBsYWJzKHg9ICJMYXVuY2ggQ291bnRzIiwgeSA9ICIiLCAKICAgICAgIGZpbGw9ICJDb3VudHJpZXMiLCAKICAgICAgIHRpdGxlPSAiWWVhcmx5IExhdW5jaCBDb3VudHMgd3J0IFByaXZhdGUgb3duZWQgQWdlbmNpZXMgaW4gZGlmZmVyZW50IGNvdW50cmllcyIpICsKICB0aGVtZShzdHJpcC50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpCgoKbGF1bmNoZXMgJT4lCiAgZmlsdGVyKGFnZW5jeV90eXBlJWluJWMoInByaXZhdGUiLCJzdGFydHVwIikpICU+JQogIGlubmVyX2pvaW4oYWdlbmNpZXMgJT4lIHNlbGVjdChhZ2VuY3ksIG5hbWUsIHNob3J0X25hbWUsIHBhcmVudCksIGJ5ID0gJ2FnZW5jeScpICU+JSAKICBjb3VudChsYXVuY2hfeWVhciwgc3RhdGVfY29kZSwgc29ydD1UKSAlPiUKICBtdXRhdGUoc3RhdGVfY29kZT1mY3RfcmVvcmRlcihzdGF0ZV9jb2RlLCBsYXVuY2hfeWVhcikpICU+JQogIHBsb3RfbHkoeD1+biwgeT0gfmxhdW5jaF95ZWFyLCBjb2xvcj1+c3RhdGVfY29kZSwgY29sb3JzPSJEYXJrMiIsIHR5cGU9J2JhcicpICU+JQogIGxheW91dChiYXJtb2RlPSdzdGFjaycsIAogICAgICAgICBsZWdlbmQgPSBULCAKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkxhdW5jaCBDb3VudHMiKSwgCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICIiLCBzaG93dGlja2xhYmVscyA9IEYpLCAKICAgICAgICAgdGl0bGUgPSAiTGF1bmNoIENvdW50cyBvZiBDb21wYW5pZXMgbm90IGhhbmRsZWQgYnkgR292ZXJubWVudCIpCmBgYAoKYGBge3J9CmxhdW5jaGVzICU+JQogIGNvdW50KGFnZW5jeV90eXBlLCBzdGF0ZV9jb2RlLCBzb3J0PVQpICU+JSAKICBtdXRhdGUoc3RhdGVfY29kZSA9IGZjdF9yZW9yZGVyKHN0YXRlX2NvZGUsIG4pKSAlPiUKICBwbG90X2x5KHg9fm4sIHk9fnN0YXRlX2NvZGUsIGNvbG9yPX5hZ2VuY3lfdHlwZSkgJT4lCiAgbGF5b3V0KGJhcm1vZGU9J3N0YWNrJywgCiAgICAgICAgIHhheGlzPWxpc3QodHlwZT0nbG9nJywgdGl0bGUgPSAiIiwgc2hvd3RpY2tsYWJlbHMgPSBGKSwgCiAgICAgICAgIHlheGlzPWxpc3QodGl0bGUgPSAiIiksIAogICAgICAgICB0aXRsZT0gJ1NwYWNlIFByb2dyYW1zIGFtb25nIENvdW50cmllcycpCgpydXNzaWFuX3ZlaGljbGVzID0gbGF1bmNoZXMgJT4lIAogIGZpbHRlcihzdGF0ZV9jb2RlPT0nUnVzc2lhJykgJT4lCiAgZ3JvdXBfYnkodHlwZSwgc3RhdGVfY29kZSkgJT4lIAogIHN1bW1hcmlzZShlYXJsaWVzdD1taW4obGF1bmNoX3llYXIpLCBsYXRlc3Q9bWF4KGxhdW5jaF95ZWFyKSwgY291bnRzPW4oKSkgJT4lCiAgdW5ncm91cCgpJT4lCiAgYXJyYW5nZSgtY291bnRzKSAlPiUgZmlsdGVyKGNvdW50cz49bWVhbihjb3VudHMpKQoKbGF1bmNoZXMgJT4lIAogIHNlbWlfam9pbihydXNzaWFuX3ZlaGljbGVzLCBieT0ndHlwZScpJT4lCiAgbXV0YXRlKHR5cGUgPSBmY3RfcmVvcmRlcih0eXBlLCBsYXVuY2hfZGF0ZSwgbWluKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxhdW5jaF9kYXRlLCB5PXR5cGUsIGNvbG9yPXR5cGUpKSArIAogIGdlb21faml0dGVyKGFscGhhPTAuMiwgaGVpZ2h0ID0gMC4yLCBzaG93LmxlZ2VuZCA9IEYpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSsgdGhlbWVfbWluaW1hbCgpKwogIGxhYnModGl0bGUgPSAnUnVzc2lhbiBTcGFjZSBWZWhpY2xlIFRpbWVsaW5lJywKICAgICAgIHN1YnRpdGxlID0gIk9ubHkgZ3JlYXRlciB0aGFuIDMwIGxhdW5jaGVzIiwKICAgICAgIHg9ICJMYXVuY2ggRGF0ZSIsIHk9IlZlaGljbGUiKQoKbGF1bmNoZXMgJT4lIAogIGZpbHRlcihzdGF0ZV9jb2RlPT0nVW5pdGVkIFN0YXRlcycpJT4lCiAgYWRkX2NvdW50KHR5cGUpICU+JSBmaWx0ZXIobj49bWVhbihuKSkgJT4lCiAgbXV0YXRlKHR5cGUgPSBmY3RfcmVvcmRlcih0eXBlLCBsYXVuY2hfZGF0ZSwgbWluKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxhdW5jaF9kYXRlLCB5PXR5cGUsIGNvbG9yPWFnZW5jeV90eXBlKSkgKyAKICBnZW9tX2ppdHRlcihhbHBoYT0wLjIsIGhlaWdodCA9IDAuMikgKyB0aGVtZV9taW5pbWFsKCkrCiAgbGFicyh0aXRsZSA9ICdVUyBTcGFjZSBWZWhpY2xlIFRpbWVsaW5lJywKICAgICAgIHg9ICJMYXVuY2ggRGF0ZSIsIHk9IlZlaGljbGUiLCBjb2xvcj0nQWdlbmN5IFR5cGUnKQoKYGBgCgo=